package com.pactera.madp.cp.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pactera.madp.common.core.exception.CheckedException;
import com.pactera.madp.cp.api.dto.workroom.WorkInternalGroupAddDTO;
import com.pactera.madp.cp.api.dto.workroom.WorkInternalGroupPageDTO;
import com.pactera.madp.cp.api.dto.workroom.WorkInternalGroupUpdateDTO;
import com.pactera.madp.cp.api.entity.BaseEntity;
import com.pactera.madp.cp.api.entity.WorkEmployeeEntity;
import com.pactera.madp.cp.api.entity.workroom.WorkInternalGroupEntity;
import com.pactera.madp.cp.api.page.SubPage;
import com.pactera.madp.cp.api.vo.workroom.WorkInternalGroupDetailsVO;
import com.pactera.madp.cp.api.vo.workroom.WorkInternalGroupListVO;
import com.pactera.madp.cp.api.vo.workroom.WorkInternalGroupPageVO;
import com.pactera.madp.cp.common.util.WxApiUtils;
import com.pactera.madp.cp.handler.CorpContextHolder;
import com.pactera.madp.cp.mapper.workroom.WorkInternalGroupMapper;
import com.pactera.madp.cp.service.ICorpService;
import com.pactera.madp.cp.service.IWorkEmployeeService;
import com.pactera.madp.cp.service.WorkInternalGroupService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;

/**
 * WorkInternalGroupServiceImpl
 *
 * @author jun
 * @version 1.0
 * 2021/8/30 11:34
 **/
@Service
@Slf4j
@AllArgsConstructor
public class WorkInternalGroupServiceImpl extends ServiceImpl<WorkInternalGroupMapper, WorkInternalGroupEntity> implements WorkInternalGroupService {

    private final ICorpService corpService;

    private final IWorkEmployeeService workEmployeeService;

    /**
     * 创建内部群聊
     * @param dto
     * @return
     */
    @Override
    public boolean saveWorkInternalGroup(WorkInternalGroupAddDTO dto) {
        Integer corpId = CorpContextHolder.getCorpId();
        String wxCorpId = corpService.getById(corpId).getWxCorpId();
        Integer agentId = corpService.getWxSendMsgAgentIdByWxCorpId(wxCorpId);

        WorkInternalGroupEntity groupEntity = getOne(Wrappers.<WorkInternalGroupEntity>lambdaQuery()
                .eq(WorkInternalGroupEntity::getCorpId, corpId)
                .eq(WorkInternalGroupEntity::getName, dto.getName()));
        if (groupEntity != null){
            throw new CheckedException("群名称重复");
        }

        AtomicBoolean flag = new AtomicBoolean(true);

//        dto.getUserList().forEach(d->{
//            if (d.equals(dto.getOwnerId())){
//                flag.set(false);
//            }
//        });
//        if (flag.get()){
//            throw new CheckedException("群主不在群成员列表中");
//        }

        dto.getUserList().add(dto.getOwnerId());
        List<Integer> collect = dto.getUserList().stream().distinct().collect(Collectors.toList());
        dto.setUserList(collect);
        //获取群主id
        WorkEmployeeEntity one = workEmployeeService.getOne(Wrappers.<WorkEmployeeEntity>lambdaQuery()
                .eq(WorkEmployeeEntity::getCorpId, corpId)
                .eq(WorkEmployeeEntity::getId, dto.getOwnerId()));

        //获取群成员id列表
        List<String> userlist = workEmployeeService.list(Wrappers.<WorkEmployeeEntity>lambdaQuery()
                .eq(WorkEmployeeEntity::getCorpId, corpId)
                .in(WorkEmployeeEntity::getId, dto.getUserList()))
                .stream().map(WorkEmployeeEntity::getWxUserId).collect(Collectors.toList());

        String chatId = WxApiUtils.saveAppChatCreate(corpId, dto.getName(), one.getWxUserId(), userlist, agentId);
        if (!StrUtil.isBlank(chatId)){
            JSONObject jsonObject = new JSONObject();
            HashMap<String, String> hashMap = new HashMap<>();
            hashMap.put("content", "群聊创建成功");
            jsonObject.put("chatid",chatId);
            jsonObject.put("msgtype", "text");
            jsonObject.put("text", hashMap);
            String sendMsgToGroupChat = WxApiUtils.sendMsgToGroupChat(jsonObject, corpId, wxCorpId);
            if (!StrUtil.isBlank(sendMsgToGroupChat) && Integer.parseInt(sendMsgToGroupChat) == 0){
                String chatGet = WxApiUtils.appChatGet(corpId, chatId, agentId);
                if (!StrUtil.isBlank(chatGet)){
                    JSONObject chat = JSONObject.parseObject(chatGet);
                    WorkInternalGroupEntity entity = new WorkInternalGroupEntity();
                    entity.setName(chat.getString("name"));
                    entity.setChatId(chatId);
                    entity.setCorpId(corpId);
                    entity.setOwner(chat.getString("owner"));
                    entity.setOwnerId(one.getId());
                    entity.setUserList(JSONUtil.formatJsonStr(chat.getString("userlist")));
                    entity.setCreateTime(DateTime.now().toTimestamp().toLocalDateTime());
                    return save(entity);
                }
            }
        }
        return false;
    }

    /**
     * 修改内部群聊
     * @param dto
     * @return
     */
    @Override
    public boolean updateWorkInternalGroup(WorkInternalGroupUpdateDTO dto) {
        Integer corpId = CorpContextHolder.getCorpId();
        String wxCorpId = corpService.getById(corpId).getWxCorpId();
        Integer agentId = corpService.getWxSendMsgAgentIdByWxCorpId(wxCorpId);

        if (!StrUtil.isBlank(dto.getName())){
            WorkInternalGroupEntity entity = getOne(Wrappers.<WorkInternalGroupEntity>lambdaQuery()
                    .eq(WorkInternalGroupEntity::getCorpId, corpId)
                    .eq(WorkInternalGroupEntity::getName, dto.getName())
                    .ne(WorkInternalGroupEntity::getId, dto.getId()));
            if (entity != null){
                throw new CheckedException("当前群名称重复");
            }
        }
        if (dto.getId() == null){
            throw new CheckedException("群id不能为空");
        }
        List<String> addUserList = new LinkedList<>();
        List<String> delUserList = new LinkedList<>();
        if (dto.getAddUserList() != null&&!dto.getAddUserList().isEmpty()){
            addUserList = workEmployeeService.list(Wrappers.<WorkEmployeeEntity>lambdaQuery()
                    .eq(WorkEmployeeEntity::getCorpId, corpId)
                    .in(WorkEmployeeEntity::getId, dto.getAddUserList()))
                    .stream().map(WorkEmployeeEntity::getWxUserId).collect(Collectors.toList());
        }

        if (dto.getDelUserList() != null&&!dto.getDelUserList().isEmpty()){
            delUserList = workEmployeeService.list(Wrappers.<WorkEmployeeEntity>lambdaQuery()
                    .eq(WorkEmployeeEntity::getCorpId, corpId)
                    .in(WorkEmployeeEntity::getId, dto.getDelUserList()))
                    .stream().map(WorkEmployeeEntity::getWxUserId).collect(Collectors.toList());
        }

        WorkInternalGroupEntity entity = getOne(Wrappers.<WorkInternalGroupEntity>lambdaQuery()
                .eq(WorkInternalGroupEntity::getCorpId, corpId)
                .eq(WorkInternalGroupEntity::getId, dto.getId()));

        String s = WxApiUtils.appChatUpdate(agentId, entity.getChatId(), dto.getName(), entity.getOwner(), addUserList, delUserList, corpId);
        if (!StrUtil.isBlank(s) && Integer.parseInt(s) == 0){
            String chatGet = WxApiUtils.appChatGet(corpId, entity.getChatId(), agentId);
            JSONObject chat = JSONObject.parseObject(chatGet);
            entity.setName(chat.getString("name"));
            entity.setOwner(chat.getString("owner"));
            entity.setUserList(JSONUtil.formatJsonStr(chat.getString("userlist")));
            WorkEmployeeEntity one = workEmployeeService.getOne(Wrappers.<WorkEmployeeEntity>lambdaQuery()
                    .eq(WorkEmployeeEntity::getCorpId, corpId)
                    .eq(WorkEmployeeEntity::getWxUserId, entity.getOwner()));
            entity.setUpdateTime(DateTime.now().toTimestamp().toLocalDateTime());
            entity.setOwnerId(one.getId());
            return updateById(entity);
        }
        return false;
    }

    /**
     * 分页查询内部表数据
     * @param page
     * @param dto
     * @return
     */
    @Override
    public Page<WorkInternalGroupPageVO> getPage(Page page, WorkInternalGroupPageDTO dto) {
        synchronizationWorkInternalGroup();
        QueryWrapper<WorkInternalGroupEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("corp_id",CorpContextHolder.getCorpId());
        wrapper.orderByDesc("create_time");
        if (!StrUtil.isBlank(dto.getName())){
            wrapper.like("name",dto.getName());
        }
        if (!StrUtil.isBlank(dto.getEndTime()) && !StrUtil.isBlank(dto.getStartTime())){
            wrapper.ge("create_time",dto.getStartTime() + " 00:00:00");
            wrapper.le("create_time",dto.getEndTime() + " 23:59:59");
        }
        IPage iPage = page(page, wrapper);
        List<WorkInternalGroupEntity> list = iPage.getRecords();
        List<WorkInternalGroupPageVO> vos = new LinkedList<>();
        list.forEach(l->{
            WorkInternalGroupPageVO vo = new WorkInternalGroupPageVO();
            BeanUtil.copyProperties(l,vo);
            WorkEmployeeEntity entity = workEmployeeService.getOne(Wrappers.<WorkEmployeeEntity>lambdaQuery()
                    .eq(WorkEmployeeEntity::getCorpId, CorpContextHolder.getCorpId())
                    .eq(WorkEmployeeEntity::getWxUserId, l.getOwner()));
            vo.setCreator(entity.getName());

            List<String> array = JSONArray.parseArray(l.getUserList(), String.class);
            List<String> collect = workEmployeeService.list(Wrappers.<WorkEmployeeEntity>lambdaQuery()
                    .eq(WorkEmployeeEntity::getCorpId, CorpContextHolder.getCorpId())
                    .in(WorkEmployeeEntity::getWxUserId, array))
                    .stream().map(WorkEmployeeEntity::getName).collect(Collectors.toList());

            vo.setUserList(collect);
            DateTimeFormatter pattern = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            vo.setCreateTime(pattern.format(l.getCreateTime()));
            vos.add(vo);
        });

        SubPage subPage = new SubPage();
        subPage.setCurrent(page.getCurrent());
        subPage.setPages(page.getPages());
        subPage.setSize(page.getSize());
        subPage.setTotal(page.getTotal());
        subPage.setRecords(vos);
        return subPage;
    }

    /**
     * 获取内部群列表
     * @return
     */
    @Override
    public List<WorkInternalGroupListVO> getList() {
        synchronizationWorkInternalGroup();

        List<WorkInternalGroupEntity> list = list(Wrappers.<WorkInternalGroupEntity>lambdaQuery()
                .eq(WorkInternalGroupEntity::getCorpId, CorpContextHolder.getCorpId())
                .orderByDesc(BaseEntity::getCreateTime));

        List<WorkInternalGroupListVO> vos = new LinkedList<>();
        list.forEach(l->{
            WorkInternalGroupListVO vo = new WorkInternalGroupListVO();
            BeanUtil.copyProperties(l,vo);

            List<String> collect = workEmployeeService.list(Wrappers.<WorkEmployeeEntity>lambdaQuery()
                    .eq(WorkEmployeeEntity::getCorpId, CorpContextHolder.getCorpId())
                    .in(WorkEmployeeEntity::getWxUserId, JSONArray.parseArray(l.getUserList(), String.class))).stream()
                    .map(WorkEmployeeEntity::getName).collect(Collectors.toList());
            vo.setUserList(collect);
            vos.add(vo);
        });

        return vos;
    }

    @Override
    public WorkInternalGroupDetailsVO getDetails(Integer id) {
        WorkInternalGroupEntity one = getOne(Wrappers.<WorkInternalGroupEntity>lambdaQuery()
                .eq(WorkInternalGroupEntity::getCorpId, CorpContextHolder.getCorpId())
                .eq(WorkInternalGroupEntity::getId, id));
        if (one == null){
            throw new CheckedException("该内部群已被删除");
        }
        WorkInternalGroupDetailsVO vo = new WorkInternalGroupDetailsVO();
        BeanUtil.copyProperties(one,vo);
        List<WorkEmployeeEntity> list = workEmployeeService.list(Wrappers.<WorkEmployeeEntity>lambdaQuery()
                .eq(WorkEmployeeEntity::getCorpId, CorpContextHolder.getCorpId())
                .in(WorkEmployeeEntity::getWxUserId,JSONArray.parseArray(one.getUserList(), String.class)));
        List<WorkInternalGroupDetailsVO.UserListClass> classes = new LinkedList<>();
        list.forEach(l->{
            WorkInternalGroupDetailsVO.UserListClass aClass = new WorkInternalGroupDetailsVO.UserListClass();
            aClass.setEmployeeId(l.getId());
            aClass.setEmployeeName(l.getName());
            classes.add(aClass);
        });
        vo.setUserList(classes);
        return vo;
    }

    /**
     * 同步内部群信息
     */
    private void synchronizationWorkInternalGroup(){
        Integer corpId = CorpContextHolder.getCorpId();
        String wxCorpId = corpService.getById(corpId).getWxCorpId();
        Integer agentId = corpService.getWxSendMsgAgentIdByWxCorpId(wxCorpId);
        List<String> collect = list(Wrappers.<WorkInternalGroupEntity>lambdaQuery().eq(WorkInternalGroupEntity::getCorpId, corpId))
                .stream().map(WorkInternalGroupEntity::getChatId).collect(Collectors.toList());

        collect.forEach(c->{
            String s = WxApiUtils.appChatGet(corpId, c, agentId);
            if (StrUtil.isBlank(s)){
                remove(Wrappers.<WorkInternalGroupEntity>lambdaQuery().eq(WorkInternalGroupEntity::getCorpId,corpId).eq(WorkInternalGroupEntity::getChatId,c));
            }
        });
    }




}
